package com.bossYang.myBatisTest.util;

import com.bossYang.myBatisTest.bean.ColumnEntity;
import com.bossYang.myBatisTest.bean.TableEntity;
import com.bossYang.myBatisTest.bean.TableTypeConstant;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

public class Excel {

	/**
	 * 读取excel并转换为表实体
	 * 
	 * @param excelPath
	 * @return
	 */
	public TableEntity readExcel(String excelPath) {
		// 解析模板对象List
		List<ColumnEntity> entities = new ArrayList<ColumnEntity>();
		// 表物理名
		String physicalTableName = null;
		// 表逻辑名
		String logicalTableName = null;
		// 数据库名
		String databaseName = null;
		try {
			// String encoding = "GBK";
			File excel = new File(excelPath);
			if (excel.isFile() && excel.exists()) { // 判断文件是否存在

				String[] split = excel.getName().split("\\."); // .是特殊字符，需要转义！！！！！
				Workbook wb;
				// 根据文件后缀（xls/xlsx）进行判断
				if ("xls".equals(split[1])) {
					FileInputStream fis = new FileInputStream(excel); // 文件流对象
					wb = new HSSFWorkbook(fis);
				} else if ("xlsx".equals(split[1])) {
					wb = new XSSFWorkbook(excel);
				} else {
					System.out.println("文件类型错误!");
					return null;
				}

				// 开始解析
				Sheet sheet = wb.getSheetAt(0); // 读取sheet 0

				int firstRowIndex = sheet.getFirstRowNum() + 2; // 第一、二行是列名，所以不读，从第三行开始读
				int lastRowIndex = sheet.getLastRowNum();
				// System.out.println("firstRowIndex: "+firstRowIndex);
				// System.out.println("lastRowIndex: "+lastRowIndex);

				// 解析模板对象List
				entities = new ArrayList<ColumnEntity>();
				// 数据库名
				databaseName = sheet.getRow(0).getCell(1).getStringCellValue();
				// 表物理名
				physicalTableName = sheet.getRow(0).getCell(3).getStringCellValue();
				// 表逻辑名
				logicalTableName = sheet.getRow(0).getCell(5).getStringCellValue();

				for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) { // 遍历行
					// System.out.println("rIndex: " + rIndex);
					ColumnEntity entity = new ColumnEntity();
					Row row = sheet.getRow(rIndex);
					if (row != null) {
						if (row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue() == null || row
								.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue().isEmpty()) {
							continue;
						}
						/*
						 * int firstCellIndex = row.getFirstCellNum(); int lastCellIndex =
						 * row.getLastCellNum(); for (int cIndex = firstCellIndex; cIndex <
						 * lastCellIndex; cIndex++) { //遍历列 Cell cell = row.getCell(cIndex); if (cell !=
						 * null) { System.out.println(cell.toString()); } }
						 */
						
						// 解析对象
						entity.setPhysicalColumnName(
								row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());// 列物理名
						entity.setLogicalColumnName(
								row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());// 列逻辑名
						entity.setType(row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());// 类型
						entity.setLength(row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());// 长度
						entity.setDecimal(row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());// 精度
						entity.setPrimaryKey("*"
								.equals(row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()));// 是否主键
						entity.setNotNull("*"
								.equals(row.getCell(6, MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()));// 是否非空
						// 存入list
						entities.add(entity);
					}
				}
			} else {
				System.out.println("找不到指定的文件");
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		TableEntity tableEntity = new TableEntity();
		tableEntity.setEntities(entities);
		tableEntity.setDatabaseName(databaseName);
		tableEntity.setLogicalTableName(logicalTableName);
		tableEntity.setPhysicalTableName(physicalTableName);
		return tableEntity;
	}

	/**
	 * 将表实体转换为sql并输出为txt
	 * 
	 * @param tableEntity
	 */
	public void convertSQL(TableEntity tableEntity) {
		StringBuffer sql = new StringBuffer();
		sql.append("CREATE TABLE `");
		sql.append(tableEntity.getDatabaseName());
		sql.append("`.`");
		sql.append(tableEntity.getPhysicalTableName());
		sql.append("` (");
		// CREATE TABLE `databaseName`.`tablePhysicalName` (
		List<ColumnEntity> cellEnties = tableEntity.getEntities();
		// 主键
		String primaryKey = null;
		// 获取主键
		for (ColumnEntity item : cellEnties) {
			// 将pk为true的设为主键
			if (item.isPrimaryKey()) {
				primaryKey = item.getPhysicalColumnName();
				break;
			}
		}
		// 循环列
		for (ColumnEntity item : cellEnties) {
			sql.append(" `");
			sql.append(item.getPhysicalColumnName().trim());
			sql.append("` ");
			// `physicalColumnName`

			// 根据NOT NULL 来拼接
			if (item.isNotNull()) { // 如果不允许为空，则拼接NOT NULL
				//类型
				String type = item.getType().toLowerCase();
				//类型转换
				if(type.indexOf("varchar")!=-1) {
					type= TableTypeConstant.VARCHAR;
				}else if (type.indexOf("number")!=-1) {
					type=TableTypeConstant.INT;
					//默认长度
					if(item.getLength()==null||item.getLength().isEmpty()) {
						item.setLength("11");
					}
				}else if(type.indexOf("char")!=-1) {
					type=TableTypeConstant.CHAR;
				}

				
				// 根据类型选择是否拼接长度
				if (TableTypeConstant.CHAR.equals(type) || TableTypeConstant.VARCHAR.equals(type)) { // 文本需要拼接长度
					sql.append(type);
					sql.append("(");
					sql.append(item.getLength());
					sql.append(") CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '");
				} else if (TableTypeConstant.TEXT.equals(type) || TableTypeConstant.LONG_TEXT.equals(type)) { // 文本不需要拼接长度
					sql.append(type);
					sql.append(" CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '");
				} else if (TableTypeConstant.DATE.equals(type)) { // 时间不需要拼接长度
					sql.append(type);
					sql.append(" NOT NULL COMMENT '");
				} else if (TableTypeConstant.DATE_TIME.equals(type)||TableTypeConstant.TIME_STAMP.equals(type)) { // 时间需要拼接长度 并且长度为0
					sql.append(type);
					sql.append("(0) NOT NULL COMMENT '");
				} else if (TableTypeConstant.INT.equals(type)) { // 数字需要拼接长度
					sql.append(type);
					sql.append("(");
					sql.append(item.getLength());
					sql.append(")  NOT NULL COMMENT '");
				}
			} else { // 如果允许为空，则拼接 NULL DEFAULT NULL
				
				String type = item.getType().toLowerCase();
				//类型转换
				if(type.indexOf("varchar")!=-1) {
					type=TableTypeConstant.VARCHAR;
				}else if (type.indexOf("number")!=-1) {
					type=TableTypeConstant.INT;
					//默认长度
					if(item.getLength()==null||item.getLength().isEmpty()) {
						item.setLength("11");
					}
				}else if(type.indexOf("char")!=-1) {
					type=TableTypeConstant.CHAR;
				}
				
				// 根据类型选择是否拼接长度
				if (TableTypeConstant.CHAR.equals(type) || TableTypeConstant.VARCHAR.equals(type)) { // 文本需要拼接长度
					sql.append(type);
					sql.append("(");
					sql.append(item.getLength());
					sql.append(") CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '");
				} else if (TableTypeConstant.TEXT.equals(type) || TableTypeConstant.LONG_TEXT.equals(type)) { // 文本不需要拼接长度
					sql.append(type);
					sql.append(" CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '");
				} else if (TableTypeConstant.DATE.equals(type)) { // 时间不需要拼接长度
					sql.append(type);
					sql.append(" NULL DEFAULT NULL COMMENT '");
				} else if (TableTypeConstant.DATE_TIME.equals(type)||TableTypeConstant.TIME_STAMP.equals(type)) { // 时间需要拼接长度 并且长度为0
					sql.append(type);
					sql.append("(0) NULL DEFAULT NULL COMMENT '");
				} else if (TableTypeConstant.INT.equals(type) || TableTypeConstant.BIG_INT.equals(type) || TableTypeConstant.LONG.equals(type)) { // 数字需要拼接长度
					sql.append(type);
					sql.append("(");
					sql.append(item.getLength());
					sql.append(")  NULL DEFAULT NULL COMMENT '");
				}
			}

			// 拼接逻辑列名
			sql.append(item.getLogicalColumnName());
			sql.append("',");
		}

		// 拼接主键
		sql.append(" PRIMARY KEY (`");
		sql.append(primaryKey);
		sql.append("`) USING BTREE ) ");
		// 拼接引擎和逻辑表名
		sql.append("ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '");
		sql.append(tableEntity.getLogicalTableName());
		sql.append("'  ROW_FORMAT = Compact;");
		System.err.println(sql);
		try {
			writeTXT("", sql.toString(), tableEntity.getPhysicalTableName() + tableEntity.getLogicalTableName());
			System.out
					.println("已导出:" + tableEntity.getPhysicalTableName() + tableEntity.getLogicalTableName() + ".txt!");
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("导出文件失败");
		}
	}

	/**
	 * 将字符串写入txt并导出
	 * 
	 * @throws Exception
	 */
	public void writeTXT(String path, String value, String fileName) throws Exception {
		File f = new File(path + fileName + ".txt");
		FileOutputStream fos1 = new FileOutputStream(f);
		OutputStreamWriter dos1 = new OutputStreamWriter(fos1);
		dos1.write(value);
		dos1.close();
	}
}

